综合示例
导航栏
- 不同页面的导航栏拥有不同的样式,当前页面的导航栏应该颜色更深
1 | function highlightPage() { |
z-index
- z-index 属性设置元素的堆叠顺序。拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面。
- Z-index 仅能在定位元素上奏效(例如 position:absolute;)
内部导航
- 点击内部导航,只出现对应的那一部分内容,其他的内容不可见。
1.传入元素ID,设置其可见,其余不可见。修改每个部分的display属性,除了作为参数传入的id对应的部分,其他部分的display属性都被设置成“none”,而与传入id对应的那个部分的display属性被设置成block。
1
2
3
4
5
6
7
8
9
10function showSection(id) {
var sections = document.getElementsByTagName("section");
for (var i=0; i<sections.length; i++ ) {
if (sections[i].getAttribute("id") != id) {
sections[i].style.display = "none";
} else {
sections[i].style.display = "block";
}
}
}2.设置onclick点击事件,传入需要可见部分的元素ID。
<article><nav><li><a href="#jay">Jay Skript</a></li></nav></article>
需要在中的 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25function prepareInternalnav() {
if (!document.getElementsByTagName) return false;
if (!document.getElementById) return false;
var articles = document.getElementsByTagName("article");
if (articles.length == 0) return false;
var navs = articles[0].getElementsByTagName("nav");
if (navs.length == 0) return false;
var nav = navs[0];
var links = nav.getElementsByTagName("a");
for (var i=0; i<links.length; i++ ) {
// array=string.split(character)数组中的第一个元素是character以前的所有字符,第二个元素是character以后的所有字符
var sectionId = links[i].getAttribute("href").split("#")[1];
//确保真的存在相应的id元素
if (!document.getElementById(sectionId)) continue;
//页面加载以后,默认隐藏所有部分
document.getElementById(sectionId).style.display = "none";
//sectionId是一个局部变量,在onclick事件处理函数时就已经不存在了,可以设置一个属性
links[i].destination = sectionId;
//事件处理函数
links[i].onclick = function() {
showSection(this.destination);
return false;
}
}
}
增强表单
- 点击label元素,关联的表单字段就会获得焦点。并不是所有的浏览器都实现了该行为。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function focusLabels() {
if (!document.getElementsByTagName) return false;
//取得文档的label元素
var labels = document.getElementsByTagName("label");
for (var i=0; i<labels.length; i++) {
//如果label有for属性,添加一个事件处理函数
if (!labels[i].getAttribute("for")) continue;
labels[i].onclick = function() {
//在label被单击时,提取for属性的值,这个值就是相应表单字段的id。
var id = this.getAttribute("for");
//确保存在相应的表单字段
if (!document.getElementById(id)) return false;
var element = document.getElementById(id);
//让相应的表单字段获得焦点
element.focus();
}
}
}
form对象和DOM
- form.elements返回input、select、textarea以及其他表单字段。childNodes返回表单中的所有节点。
每个表单元素都有自己的一组属性。element.value与element.getAttribute(“value”)等价。
在不支持placeholder属性的浏览器中也能实现就编写如下方法。这个方法与11章的方法类似,只是用的是HTML的form方法,11章用的是DOM方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29function resetFields(whichform) {
//检查浏览器是否支持placeholder属性,如果不支持,继续
if (Modernizr.input.placeholder) return;
//循环遍历表单中的每个元素
for (var i=0; i<whichform.elements.length; i++) {
var element = whichform.elements[i];
//如果当前元素是提交按钮,跳过。
if (element.type == "submit") continue;
//如果没有placeholder属性,继续。
if (!element.getAttribute('placeholder')) continue;
//元素获得焦点的事件添加一个处理函数。如果字段的值等于占位符文本,则将字段的值设置为空
element.onfocus = function() {
if (this.value == this.getAttribute('placeholder')) {
this.value = "";
}
}
//元素失去焦点的事件添加一个处理函数。如果字段的值为空,则将字段的值设置为占位符
element.onblur = function() {
if (this.value == "") {
//为了应用样式,在字段显示占位符值的时候,添加placeholder类
this.className='placeholder';
//鉴于不同的浏览器对位置属性的实现方式有所不同。同时使用了DOM placeholder属性和DOM的getAttribute('placeholder')方法
this.value = this.getAttribute('placeholder')|| this.getAttribute('placeholder');
}
}
element.onblur();
}
}
表单验证
使用JS验证表单的注意事项
- 验证脚本写的不好,反而不如没有验证
- 千万不要完全依赖JS。客户端验证并不能取代服务器端的验证。即使有了JS验证,服务器照样还应该对接收到的数据再次验证。
- 客户端验证的目的在于帮助用户填好表单,避免他们提交未完成的表单,从而节省他们的时间。服务器验证的目的在于保证数据库和后台系统的安全。
1 | //表单验证 |
Ajax
- 提交表单能够发送一个Ajax请求,感谢信息以嵌入方式添加到表单所在的页面,体验会更好。就是表单提交成功后,不打开新页面了,而是拦截请求,自己显示结果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86//创建XMLHttpRequest对象
function getHTTPObject() {
if (typeof XMLHttpRequest == "undefined")
XMLHttpRequest = function () {
try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
catch (e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
catch (e) {}
try { return new ActiveXObject("Msxml2.XMLHTTP"); }
catch (e) {}
return false;
}
return new XMLHttpRequest();
}
//展示loading图片
function displayAjaxLoading(element) {
// 删除所有子元素
while (element.hasChildNodes()) {
element.removeChild(element.lastChild);
}
// 创建一个图像元素
var content = document.createElement("img");
content.setAttribute("src","images/loading.gif");
content.setAttribute("alt","Loading...");
// 将图像添加到该元素中
element.appendChild(content);
}
function submitFormWithAjax( whichform, thetarget ) {
//在修改DOM和显示加载图像之前,首先要检查是否存在有效的XMLHttpRequest对象
var request = getHTTPObject();
if (!request) { return false; }
//调用displayAjaxLoading函数,删除目标元素的子元素,并添加loading.gif图像
displayAjaxLoading(thetarget);
//循环遍历表单的每个字段,手机他们的名字和编码后的值
var dataParts = [];
var element;
for (var i=0; i<whichform.elements.length; i++) {
element = whichform.elements[i];
dataParts[i] = element.name + '=' + encodeURIComponent(element.value);
}
//收集到所有数据后,把数组中的项用和号&连接起来
var data = dataParts.join('&');
//向原始表单的action属性指定的处理函数发送post请求
request.open('POST', whichform.getAttribute("action"), true);
//并在请求头部添加application/x-www-form-urlencoded头部。这个头部信息对于POST请求是必须的,它表示请求中包含URL编码的表单
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.onreadystatechange = function () {
if (request.readyState == 4) {
if (request.status == 200 || request.status == 0) {
//数组matches的第一个元素是responseText中的整个模式匹配的部分,即包括<article>和</article>在内的部分
//数组matches的第二个元素responseText中与补货组中的模式匹配的部分
var matches = request.responseText.match(/<article>([\s\S]+)<\/article>/);
if (matches.length > 0) {
thetarget.innerHTML = matches[1];
} else {
thetarget.innerHTML = '<p>Oops, there was an error. Sorry.</p>';
}
} else {
thetarget.innerHTML = '<p>' + request.statusText + '</p>';
}
}
};
request.send(data);
return true;
};
//提交表单触发的onclick按钮
function prepareForms() {
for (var i=0; i<document.forms.length; i++) {
var thisform = document.forms[i];
resetFields(thisform);
thisform.onsubmit = function() {
//如果表单没有通过验证,就返回false.验证失败,不能提交表单
if (!validateForm(this)) return false;
var article = document.getElementsByTagName('article')[0];
//submitFormWithAjax函数成功发送了Ajax请求并返回true,则让submit事件处理函数返回false,以便阻止浏览器重复提交表单
if (submitFormWithAjax(this, article)) return false;
//submitFormWithAjax函数没有成功发送了Ajax请求,故submit事件返回true,让表单 像什么也没有发生一样继续通过页面提交
return true;
}
}
}
压缩代码
- 谷歌的closure Compiler可以压缩代码